import { notification } from 'antd'
import { PageLoading, Settings as LayoutSettings } from '@ant-design/pro-layout'
import { RequestInterceptor, RequestOptionsInit, ResponseInterceptor } from 'umi-request'
import { fetchUserInfo } from '@/services/user'
import NProgress from 'nprogress'
import defaultSettings from '../config/default-settings'
import { history, RequestConfig } from 'umi'
import { BASE_URL, CodeMessage, LoginPath } from './common/constants'
import { removeToken } from './utils/auth'
import { APP } from './types/global'

export const initialStateConfig = {
  loading: <PageLoading />,
}

export async function getInitialState(): Promise<{
  settings?: LayoutSettings
  currentUser?: API.CurrentUser
  getUserInfo?: () => Promise<API.CurrentUser | undefined>
}> {
  NProgress.done()
  const getUserInfo = async () => {
    try {
      const { data } = await fetchUserInfo()
      return data
    } catch (error) {
      history.push(LoginPath)
    }
    return undefined
  }

  return {
    getUserInfo,
    settings: defaultSettings,
  }
}

// 异常处理程序
const errorHandler = (error: APP.CustomResponseError) => {
  const { response } = error
  if (response?.status) {
    const errorText = CodeMessage[response.status] || response.statusText
    const { status, url } = response

    notification.error({
      message: `请求错误 ${status}: ${url}`,
      description: errorText,
    })
  }

  const httpCode = error?.response?.status

  NProgress.done()

  // 登录过期
  if (httpCode === 401) {
    removeToken()
    history.replace(LoginPath)
    return
  }

  if (!response) {
    notification.error({
      description: '您的网络发生异常，无法连接服务器',
      message: '网络异常',
    })
  }
  throw error
}

const authHeaderInterceptor: RequestInterceptor = (url: string, options: RequestOptionsInit) => {
  NProgress.start()
  const obj: any = options
  if (localStorage.getItem('token')) {
    const token = localStorage.getItem('token')
    obj.headers = {
      ...obj.headers,
      Authorization: token || '',
      'Content-Type': 'application/json',
    }
  }
  return { url, obj }
}

const handleResponse: ResponseInterceptor = async (response: Response) => {
  const res = await response.clone().json()
  const { code, msg } = res

  NProgress.done()

  if (code !== 0) {
    notification.error({
      message: '请求错误',
      description: `${code}: ${msg}`,
    })
    return
  }

  return res
}

export const request: RequestConfig = {
  errorHandler,
  credentials: 'include',
  prefix: BASE_URL,
  timeout: 1000,
  requestInterceptors: [authHeaderInterceptor],
  responseInterceptors: [handleResponse],
}
